Add initial VMX support to xm-test:
authorstekloff@elm3b216.beaverton.ibm.com <stekloff@elm3b216.beaverton.ibm.com>
Fri, 9 Dec 2005 11:04:55 +0000 (11:04 +0000)
committerstekloff@elm3b216.beaverton.ibm.com <stekloff@elm3b216.beaverton.ibm.com>
Fri, 9 Dec 2005 11:04:55 +0000 (11:04 +0000)
1) Added script create_disk_image to make full virt image
2) Changed XenDomain.py to build separate XmTestDomain object
   for vmx guests (this structure will need to be cleaned up)
3) Changed ramdisk Makefile.am to create disk.img if vmx configured

Signed-off-by: Daniel Stekloff <dsteklof@us.ibm.com>
tools/xm-test/configure.ac
tools/xm-test/lib/XmTestLib/XenDomain.py
tools/xm-test/lib/XmTestLib/config.py.in
tools/xm-test/ramdisk/Makefile.am
tools/xm-test/ramdisk/bin/create_disk_image [new file with mode: 0644]
tools/xm-test/tests/block-list/04_block-list_nodb_pos.py

index dae815a6694da9c7612b56519b51989981175446..4a606e611c74343a5ffe06f2a1585f1585666d65 100644 (file)
@@ -15,13 +15,14 @@ RD_PATH=../../ramdisk
 TENV="PYTHONPATH=$PYTHONPATH:$TESTLIB:/usr/lib/python RD_PATH=$RD_PATH"
 
 AC_ARG_ENABLE(vmx-support,
-       [[  --enable-vmx-support           use block devices instead of ramdisks]],
+       [[  --enable-vmx-support           enable hardware virtual machine assist]],
        [
                ENABLE_VMX=True
        ],[
                ENABLE_VMX=False
        ])
 
+AM_CONDITIONAL(VMX, test x$ENABLE_VMX = xTrue)
 AC_SUBST(ENABLE_VMX)
 
 AC_SUBST(TENV)
index 0b07ae98352c73d980b15d9fff2f4b5729511385..4ea9c66f93e5a2e78fad7c5359985e503e9fa12b 100644 (file)
@@ -23,13 +23,18 @@ import commands
 import os
 import re
 import time
-import random
 
 from Xm import *
 from Test import *
 from config import *
 
-BLOCK_ROOT_DEV = "hdd1"
+BLOCK_ROOT_DEV = "hda"
+
+def XmTestDomain(name=None, extraOpts=None, config="/dev/null"):
+    if ENABLE_VMX_SUPPORT:
+        return XmTestVmxDomain(name, extraOpts, config)
+    else:
+        return XmTestPvDomain(name, extraOpts, config)
 
 def getDefaultKernel():
     dom0Ver = commands.getoutput("uname -r");
@@ -77,7 +82,21 @@ class XenDomain:
             c += " %s=%s" % (k, self.opts[k])
         
         return c
-        
+
+    def getUniqueName(self):
+        #
+        # We avoid multiple duplicate names
+        # here because they stick around in xend
+        # too long
+        #
+        unixtime = int(time.time())
+        test_name = sys.argv[0]
+        test_name = re.sub("\.test", "", test_name)
+        test_name = re.sub("[\/\.]", "", test_name)
+        name = "%s-%i" % (test_name, unixtime)
+
+        return name
+
     def start(self):
 
         if self.configVals:
@@ -135,6 +154,18 @@ class XenDomain:
 
         self.configVals["disk"].append("%s,%s,%s" % (pdev,vdev,acc))
 
+    def configAddVif(self, type, mac, bridge):
+        if not self.configVals:
+            self.configVals = {}
+
+        if not self.configVals.has_key("vif"):
+            self.configVals["vif"] = []
+
+        if mac:
+            self.configVals["vif"].append("%s,%s,%s" % (type,mac,bridge))
+        else:
+            self.configVals["vif"].append("%s,%s" % (type,bridge))
+
     def __writeConfig(self, configFileName):
 
         conf = file(configFileName, "w")
@@ -144,46 +175,84 @@ class XenDomain:
 
         conf.close()
 
+class XmTestVmxDomain(XenDomain):
 
-class XmTestDomain(XenDomain):
+    def __prepareBlockRoot(self, rdpath):
+        image = os.path.abspath(rdpath + "/disk.img")
+        self.configAddDisk("file:%s" % image, "ioemu:%s" % BLOCK_ROOT_DEV, "w")
 
-    def __getUniqueName(self):
-        #
-        # We avoid multiple duplicate names
-        # here because they stick around in xend
-        # too long
-        #
-        unixtime = int(time.time())
-        test_name = sys.argv[0]
-        test_name = re.sub("\.test", "", test_name)
-        test_name = re.sub("[\/\.]", "", test_name)
-        name = "%s-%i" % (test_name, unixtime)
+    def __prepareVif(self):
+        self.configAddVif("type=ioemu", None, "bridge=xenbr0")
 
-        return name
+    def __prepareDeviceModel(self):
+        arch = os.uname()[4]
+        if re.search('64', arch):
+            self.configSetVar("device_model", "\"/usr/lib64/xen/bin/qemu-dm\"")
+        else:
+            self.configSetVar("device_model", "\"/usr/lib/xen/bin/qemu-dm\"")
 
-    def __randomize(self):
-        # Random amount of memory between min and free_memory/2
-        freeMem = int(getInfo("free_memory"))
-        self.defaults["memory"] = random.randint(self.minSafeMem(),
-                                                 freeMem/2)
-        
-        self.defaults["vcpus"] = random.randint(1, 16)
+    def __init__(self, name=None, extraOpts=None, config="/dev/null"):
+
+        rdpath = os.environ.get("RD_PATH")
+        if not rdpath:
+            rdpath = "../../ramdisk"
 
-        self.defaults["nics"] = random.randint(0, 8)
+        self.opts = {}
+        self.configVals = {}
 
-        if verbose:
-            print "*** Defaults after randomization:"
-            for k in self.defaults.keys():
-                print "***  %10s : %s" % (k, self.defaults[k])
+        # Defaults
+        self.defaults = {"memory"    : 64,
+                         "vcpus"     : 1,
+                         "nics"      : 0,
+                         "kernel"    : "/usr/lib/xen/boot/vmxloader",
+                         "builder"   : "\'vmx\'",
+                         "name"      : name or self.getUniqueName()
+                         }
 
-    def __prepareBlockRoot(self, rdpath):
-        image = os.path.abspath(rdpath + "/initrd.img")
-        self.configAddDisk("file:%s" % image, BLOCK_ROOT_DEV, "w")
-        self.defaults["root"] = "/dev/%s" % BLOCK_ROOT_DEV
-        del self.defaults["ramdisk"]
+        self.domID = None;
+        self.config = config;
+
+        self.__prepareBlockRoot(rdpath)
+       #self.__prepareVif()
+        self.__prepareDeviceModel()
+        #self.configSetVar("boot","\'c\'")
+        self.configSetVar("sdl","0")
+        self.configSetVar("vnc","0")
+        self.configSetVar("vncviewer","0")
+        self.configSetVar("nographic","1")
+        self.configSetVar("serial","\'pty\'")
 
-    def __init__(self, name=None, extraOpts=None, config="/dev/null",
-                 random=False):
+        # Copy over defaults
+        for key in self.defaults.keys():
+            self.opts[key] = self.defaults[key]
+
+        # Merge in extra options
+        if extraOpts:
+            for key in extraOpts.keys():
+                self.opts[key] = extraOpts[key]
+
+    def start(self):
+        """We know how about how long everyone will need to wait
+        for our disk image to come up, so we do it here as a convenience"""
+
+#        for i in range(0,5):
+#            status, output = traceCommand("xm list")
+
+        XenDomain.start(self)
+        waitForBoot()
+
+    def startNow(self):
+        XenDomain.start(self)
+
+    def getMem(self):
+        return int(self.opts["memory"])
+
+    def minSafeMem(self):
+        return 16
+
+class XmTestPvDomain(XenDomain):
+
+    def __init__(self, name=None, extraOpts=None, config="/dev/null"):
 
         rdpath = os.environ.get("RD_PATH")
         if not rdpath:
@@ -198,19 +267,13 @@ class XmTestDomain(XenDomain):
                          "nics"    : 0,
                          "kernel"  : getDefaultKernel(),
                          "root"    : "/dev/ram0",
-                         "name"    : name or self.__getUniqueName(),
+                         "name"    : name or self.getUniqueName(),
                          "ramdisk" : rdpath + "/initrd.img"
                          }
 
         self.domID = None;
         self.config = config;
 
-        if random:
-            self.__randomize()
-
-        if USE_BLKDEV_FOR_ROOT:
-            self.__prepareBlockRoot(rdpath)
-        
         # Copy over defaults
         for key in self.defaults.keys():
             self.opts[key] = self.defaults[key]
index fde2fa472cbfe3a9e106f01733dd88128eb0d131..86e7cf7a2cfd6e36ca72dbd74345d53cba44dc5a 100644 (file)
@@ -1,4 +1,4 @@
 #!/usr/bin/python
 
-USE_BLKDEV_FOR_ROOT = @ENABLE_VMX@
+ENABLE_VMX_SUPPORT = @ENABLE_VMX@
 
index d83aee56caf0c3e0cf0ba1e741f9f4a52940e378..75811dce783cf3570af6929456a8097ee30e84b2 100644 (file)
@@ -9,10 +9,16 @@ BR_IMG = $(BR_SRC)/rootfs.i386.ext2
 
 BR_ROOT = build_i386/root
 
+VMX_SCRIPT = bin/create_disk_image
+
 XMTEST_MAJ_VER = $(shell echo @PACKAGE_VERSION@ | perl -pe 's/(\d+)\.(\d+)\.\d+/\1.\2/')
 XMTEST_VER_IMG = initrd-$(XMTEST_MAJ_VER).img
 
+if VMX
+all: initrd.img disk.img
+else
 all: initrd.img
+endif
 
 $(BR_TAR):
        wget $(BR_URL)
@@ -37,6 +43,10 @@ $(XMTEST_VER_IMG): $(BR_IMG)
 initrd.img: $(XMTEST_VER_IMG)
        ln -sf $(XMTEST_VER_IMG) initrd.img
 
+disk.img: $(XMTEST_VER_IMG)
+       chmod a+x $(VMX_SCRIPT)
+       $(VMX_SCRIPT) -r $(XMTEST_VER_IMG) -i disk.img
+
 existing:
        @[ -f $(XMTEST_VER_IMG) ] && ln -sf $(XMTEST_VER_IMG) initrd.img || \
        echo Error, $(XMTEST_VER_IMG) not found
@@ -49,3 +59,4 @@ am_config_clean-local:
        rm -f initrd.img
        rm -f $(BR_TAR)
        rm -Rf patches make.d
+       rm -f disk.img
diff --git a/tools/xm-test/ramdisk/bin/create_disk_image b/tools/xm-test/ramdisk/bin/create_disk_image
new file mode 100644 (file)
index 0000000..0d6ba67
--- /dev/null
@@ -0,0 +1,317 @@
+#!/bin/bash
+###############################################################################
+##
+##  Copyright (C) International Business Machines  Corp., 2005
+##  Author(s):  Daniel Stekloff <dsteklof@us.ibm.com>
+##
+##  This program is free software; you can redistribute it and/or modify
+##  it under the terms of the GNU General Public License as published by
+##  the Free Software Foundation; under version 2 of the License.
+##
+##  This program is distributed in the hope that it will be useful,
+##  but WITHOUT ANY WARRANTY; without even the implied warranty of
+##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+##  GNU General Public License for more details.
+##
+##  You should have received a copy of the GNU General Public License
+##  along with this program; if not, write to the Free Software
+##  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+##
+###############################################################################
+function cleanup()
+{
+       if [ "$LOOPD" ]; then
+               losetup -d $LOOPD
+       fi
+       if [ "$LOOPP" ]; then
+               losetup -d $LOOPP
+       fi
+       if  [ -e "$IMAGE" ]; then
+               rm -f "$IMAGE"
+       fi
+       if  [ -e "$LCONF" ]; then
+               rm -f "$LCONF"
+       fi
+}
+
+function die()
+{
+       cleanup
+       echo "$@"
+       exit 1
+}
+
+function usage()
+{
+       cat << EOU
+Command creates a vmx guest disk image for xm-test. 
+
+Usage: $0 [OPTIONS]
+
+OPTIONS:
+    -i|--image <name>        Image name to create.
+    -k|--kernel <name>       Kernel name to use for disk image.
+    -r|--rootfs <image>      Rootfs image to use for disk image.
+
+EOU
+}
+
+function check_dependencies()
+{
+       which lilo > /dev/null 2>&1
+       if [ $? -ne 0 ]; then
+               die "$PROGNAME requires lilo version 22.7+ to be installed."
+       fi
+       local pass="$( lilo -V | cut -f3 -d " " | awk -F "." '
+               {
+                       if ($1 >= 22 && $2 >= 7)
+                               print "true"
+                       else
+                               print "false"
+               }')"
+       if [ $pass = "false" ]; then
+               die "$PROGNAME requires lilo version 22.7+ to be installed."
+       fi
+}
+
+function initialize_globals()
+{
+       PROGNAME="create_disk_image"
+       IMAGE="hvm.img"
+       KERNEL=""
+       LCONF="lilo.conf"
+       LOOPD=""    # Loop device for entire disk image
+       LOOPP=""    # Loop device for ext partition
+       ROOTFS=""
+       MNT="/tmp/$PROGNAME-mnt"
+       SIZE=8192
+       SECTORS=32
+       HEADS=8
+       CYLINDERS=$(($SIZE/$SECTORS/$HEADS*2))
+       BSIZE=$(($SIZE-$SECTORS))
+       OFFSET=$(($SECTORS*512))
+}
+
+function get_options()
+{
+       while [ $# -gt 0 ]; do
+               case $1 in
+                       -i|--image)
+                               shift
+                               IMAGE=${1}
+                               shift
+                               ;;
+                       -k|--kernel)
+                               shift
+                               KERNEL=${1}
+                               shift
+                               ;;
+                       -r|--rootfs)
+                               shift
+                               ROOTFS=${1}
+                               shift
+                               ;;
+                       *)
+                               usage
+                               exit 1
+                               ;;
+               esac
+       done
+}
+
+function get_loopd()
+{
+       local loop
+
+       for i in `seq 0 7`; do
+               losetup /dev/loop$i > /dev/null 2>&1
+               if [ $? -ne 0 ]; then
+                       # found one
+                       echo $i
+                       return 0
+               fi
+       done
+       die "No free loopback devices."
+}
+
+function losetup_image()
+{
+       local loop=$1
+       shift
+
+       # If offset, then associate with it
+       if [ $# -eq 1 ]; then
+               losetup -o $1 $loop $IMAGE
+       else
+               losetup $loop $IMAGE
+       fi
+
+       if [ $? -ne 0 ]; then
+               die "Failed to losetup $IMAGE to $loop."
+       fi
+
+       echo "Associated $IMAGE with $loop"
+}
+
+function create_disk_image()
+{
+       dd bs=1024 count=$SIZE of=$IMAGE if=/dev/zero
+
+       fdisk -b 512 -C $CYLINDERS -H $HEADS -S $SECTORS "$IMAGE" > /dev/null 2>&1 << EOF
+n
+p
+1
+1
+
+a
+1
+w
+EOF
+}
+
+function makefs_image()
+{
+       mke2fs -N 24 -b 1024 $LOOPP $BSIZE
+
+       if [ $? -ne 0 ]; then
+               die "mke2fs $LOOPP failed."
+       fi
+}
+
+function dd_rootfs_to_image()
+{
+       if [ ! "$ROOTFS" ]; then
+               die "Must specify rootfs image to use."
+       fi
+
+       dd if="$ROOTFS" of="$LOOPP" > /dev/null 2>&1
+       if [ $? -ne 0 ]; then
+               die "Failed to dd $ROOTFS to $LOOPP."
+       fi
+}
+
+function get_kernel()
+{
+       # look in /boot for an existing kernel
+       local -a kernels=( `ls /boot | grep vmlinuz` )
+       local k
+
+       for k in ${kernels[@]}; do
+               case "$k" in
+                       *xen*)
+                               continue
+                               ;;
+                       *)
+                               KERNEL="/boot/$k"
+                               echo "Using kernel $KERNEL"
+                               break
+                               ;;
+               esac
+       done
+}
+
+function copy_kernel_to_image()
+{
+       if [ ! "$KERNEL" ]; then
+               get_kernel || die "Couldn't find a kernel to use."
+       fi
+
+       mkdir "$MNT/boot"
+
+       cp "$KERNEL" "$MNT/boot"
+}
+
+function lilo_image()
+{
+       local kernel=`basename $KERNEL`
+
+       (
+       cat <<EOC
+boot=$LOOPD
+delay=10
+geometric
+map=$MNT/boot/map
+disk=$LOOPD
+        bios=0x80
+        sectors=$SECTORS
+        heads=$HEADS
+        cylinders=$CYLINDERS
+        partition=$LOOPP
+                start=$SECTORS
+image=$MNT/boot/$kernel
+       append="root=0301 console=tty0 console=ttyS0"
+#      append="root=0301"
+        label=Linux
+        read-only
+EOC
+       ) > "/$MNT/boot/$LCONF"
+}
+
+function install_lilo()
+{
+       lilo -C "$MNT/boot/$LCONF"
+       if [ $? -ne 0 ]; then
+               die "Failed to install $MNT/boot/$LCONF."
+       fi
+}
+
+function add_getty_to_inittab()
+{
+       local itab=$MNT/etc/inittab
+
+       if [ -e "$itab" ]; then
+               echo "# Start getty on serial line" >> $itab
+               echo "S0:12345:respawn:/sbin/getty ttyS0" >> $itab
+       fi
+}
+
+
+# Main starts here
+initialize_globals
+check_dependencies
+
+get_options "$@"
+
+create_disk_image
+
+# Get the first free loop device
+ldev=$(get_loopd)
+LOOPD="/dev/loop$ldev"
+losetup_image $LOOPD
+
+# Now associate where the partition will go
+ldev=$(get_loopd)
+LOOPP="/dev/loop$ldev"
+losetup_image $LOOPP $OFFSET
+
+makefs_image
+
+dd_rootfs_to_image
+
+if [ -e "$MNT" ]; then
+       rm -Rf "$MNT"
+fi
+
+mkdir "$MNT";
+if [ $? -ne 0 ]; then
+       die "Failed to create temporary mount point $MNT."
+fi
+
+mount "$LOOPP" "$MNT";
+if [ $? -ne 0 ]; then
+       die "Failed to mount $LOOPP on $MNT."
+fi
+
+copy_kernel_to_image
+#add_getty_to_inittab
+
+lilo_image
+install_lilo
+
+umount "$MNT"
+rm -Rf "$MNT";
+
+losetup -d $LOOPD
+losetup -d $LOOPP
+
+exit 0
index f168a346ba012b02cc4257afeb9b8ba328aacf4b..4c2ce2a9efe8215cc4d9b586ada4c646f78e1cc8 100644 (file)
@@ -21,7 +21,7 @@ status, output = traceCommand("xm block-list %s" % domain.getId())
 if status != 0:
     FAIL("xm block-list returned bad status, expected 0, status is %i" % status)
 
-if USE_BLKDEV_FOR_ROOT:
+if ENABLE_VMX_SUPPORT:
     SKIP("Using block device for root, so this case does not apply")
 
 if output != "":